home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2000 March / maximum-cd-2000-03.iso / Quake3 Game Source / Q3AGameSource.exe / Main / ui_sppostgame.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-18  |  18.1 KB  |  620 lines

  1. // Copyright (C) 1999-2000 Id Software, Inc.
  2. //
  3. /*
  4. =============================================================================
  5.  
  6. SINGLE PLAYER POSTGAME MENU
  7.  
  8. =============================================================================
  9. */
  10.  
  11. #include "ui_local.h"
  12.  
  13. #define MAX_SCOREBOARD_CLIENTS        8
  14.  
  15. #define AWARD_PRESENTATION_TIME        2000
  16.  
  17. #define ART_MENU0        "menu/art/menu_0"
  18. #define ART_MENU1        "menu/art/menu_1"
  19. #define ART_REPLAY0        "menu/art/replay_0"
  20. #define ART_REPLAY1        "menu/art/replay_1"
  21. #define ART_NEXT0        "menu/art/next_0"
  22. #define ART_NEXT1        "menu/art/next_1"
  23.  
  24. #define ID_AGAIN        10
  25. #define ID_NEXT            11
  26. #define ID_MENU            12
  27.  
  28. typedef struct {
  29.     menuframework_s    menu;
  30.     menubitmap_s    item_again;
  31.     menubitmap_s    item_next;
  32.     menubitmap_s    item_menu;
  33.  
  34.     int                phase;
  35.     int                ignoreKeysTime;
  36.     int                starttime;
  37.     int                scoreboardtime;
  38.     int                serverId;
  39.  
  40.     int                clientNums[MAX_SCOREBOARD_CLIENTS];
  41.     int                ranks[MAX_SCOREBOARD_CLIENTS];
  42.     int                scores[MAX_SCOREBOARD_CLIENTS];
  43.  
  44.     char            placeNames[3][64];
  45.  
  46.     int                level;
  47.     int                numClients;
  48.     int                won;
  49.     int                numAwards;
  50.     int                awardsEarned[6];
  51.     int                awardsLevels[6];
  52.     qboolean        playedSound[6];
  53.     int                lastTier;
  54.     sfxHandle_t        winnerSound;
  55. } postgameMenuInfo_t;
  56.  
  57. static postgameMenuInfo_t    postgameMenuInfo;
  58. static char                    arenainfo[MAX_INFO_VALUE];
  59.  
  60. char    *ui_medalNames[] = {"Accuracy", "Impressive", "Excellent", "Gauntlet", "Frags", "Perfect"};
  61. char    *ui_medalPicNames[] = {
  62.     "menu/medals/medal_accuracy",
  63.     "menu/medals/medal_impressive",
  64.     "menu/medals/medal_excellent",
  65.     "menu/medals/medal_gauntlet",
  66.     "menu/medals/medal_frags",
  67.     "menu/medals/medal_victory"
  68. };
  69. char    *ui_medalSounds[] = {
  70.     "sound/feedback/accuracy.wav",
  71.     "sound/feedback/impressive_a.wav",
  72.     "sound/feedback/excellent_a.wav",
  73.     "sound/feedback/gauntlet.wav",
  74.     "sound/feedback/frags.wav",
  75.     "sound/feedback/perfect.wav"
  76. };
  77.  
  78.  
  79. /*
  80. =================
  81. UI_SPPostgameMenu_AgainEvent
  82. =================
  83. */
  84. static void UI_SPPostgameMenu_AgainEvent( void* ptr, int event )
  85. {
  86.     if (event != QM_ACTIVATED) {
  87.         return;
  88.     }
  89.     UI_PopMenu();
  90.     trap_Cmd_ExecuteText( EXEC_APPEND, "map_restart 0\n" );
  91. }
  92.  
  93.  
  94. /*
  95. =================
  96. UI_SPPostgameMenu_NextEvent
  97. =================
  98. */
  99. static void UI_SPPostgameMenu_NextEvent( void* ptr, int event ) {
  100.     int            currentSet;
  101.     int            levelSet;
  102.     int            level;
  103.     int            currentLevel;
  104.     const char    *arenaInfo;
  105.  
  106.     if (event != QM_ACTIVATED) {
  107.         return;
  108.     }
  109.     UI_PopMenu();
  110.  
  111.     // handle specially if we just won the training map
  112.     if( postgameMenuInfo.won == 0 ) {
  113.         level = 0;
  114.     }
  115.     else {
  116.         level = postgameMenuInfo.level + 1;
  117.     }
  118.     levelSet = level / ARENAS_PER_TIER;
  119.  
  120.     currentLevel = UI_GetCurrentGame();
  121.     if( currentLevel == -1 ) {
  122.         currentLevel = postgameMenuInfo.level;
  123.     }
  124.     currentSet = currentLevel / ARENAS_PER_TIER;
  125.  
  126.     if( levelSet > currentSet || levelSet == UI_GetNumSPTiers() ) {
  127.         level = currentLevel;
  128.     }
  129.  
  130.     arenaInfo = UI_GetArenaInfoByNumber( level );
  131.     if ( !arenaInfo ) {
  132.         return;
  133.     }
  134.  
  135.     UI_SPArena_Start( arenaInfo );
  136. }
  137.  
  138.  
  139. /*
  140. =================
  141. UI_SPPostgameMenu_MenuEvent
  142. =================
  143. */
  144. static void UI_SPPostgameMenu_MenuEvent( void* ptr, int event )
  145. {
  146.     if (event != QM_ACTIVATED) {
  147.         return;
  148.     }
  149.     UI_PopMenu();
  150.     trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect; levelselect\n" );
  151. }
  152.  
  153.  
  154. /*
  155. =================
  156. UI_SPPostgameMenu_MenuKey
  157. =================
  158. */
  159. static sfxHandle_t UI_SPPostgameMenu_MenuKey( int key ) {
  160.     if ( uis.realtime < postgameMenuInfo.ignoreKeysTime ) {
  161.         return 0;
  162.     }
  163.  
  164.     if( postgameMenuInfo.phase == 1 ) {
  165.         trap_Cmd_ExecuteText( EXEC_APPEND, "abort_podium\n" );
  166.         postgameMenuInfo.phase = 2;
  167.         postgameMenuInfo.starttime = uis.realtime;
  168.         postgameMenuInfo.ignoreKeysTime    = uis.realtime + 250;
  169.         return 0;
  170.     }
  171.  
  172.     if( postgameMenuInfo.phase == 2 ) {
  173.         postgameMenuInfo.phase = 3;
  174.         postgameMenuInfo.starttime = uis.realtime;
  175.         postgameMenuInfo.ignoreKeysTime    = uis.realtime + 250;
  176.         return 0;
  177.     }
  178.  
  179.     if( key == K_ESCAPE || key == K_MOUSE2 ) {
  180.         return 0;
  181.     }
  182.  
  183.     return Menu_DefaultKey( &postgameMenuInfo.menu, key );
  184. }
  185.  
  186.  
  187. static int medalLocations[6] = {144, 448, 88, 504, 32, 560};
  188.  
  189. static void UI_SPPostgameMenu_DrawAwardsMedals( int max ) {
  190.     int        n;
  191.     int        medal;
  192.     int        amount;
  193.     int        x, y;
  194.     char    buf[16];
  195.  
  196.     for( n = 0; n < max; n++ ) {
  197.         x = medalLocations[n];
  198.         y = 64;
  199.         medal = postgameMenuInfo.awardsEarned[n];
  200.         amount = postgameMenuInfo.awardsLevels[n];
  201.  
  202.         UI_DrawNamedPic( x, y, 48, 48, ui_medalPicNames[medal] );
  203.  
  204.         if( medal == AWARD_ACCURACY ) {
  205.             Com_sprintf( buf, sizeof(buf), "%i%%", amount );
  206.         }
  207.         else {
  208.             if( amount == 1 ) {
  209.                 continue;
  210.             }
  211.             Com_sprintf( buf, sizeof(buf), "%i", amount );
  212.         }
  213.  
  214.         UI_DrawString( x + 24, y + 52, buf, UI_CENTER, color_yellow );
  215.     }
  216. }
  217.  
  218.  
  219. static void UI_SPPostgameMenu_DrawAwardsPresentation( int timer ) {
  220.     int        awardNum;
  221.     int        atimer;
  222.     vec4_t    color;
  223.  
  224.     awardNum = timer / AWARD_PRESENTATION_TIME;
  225.     atimer = timer % AWARD_PRESENTATION_TIME;
  226.  
  227.     color[0] = color[1] = color[2] = 1.0f;
  228.     color[3] = (float)( AWARD_PRESENTATION_TIME - atimer ) / (float)AWARD_PRESENTATION_TIME;
  229.     UI_DrawProportionalString( 320, 64, ui_medalNames[postgameMenuInfo.awardsEarned[awardNum]], UI_CENTER, color );
  230.  
  231.     UI_SPPostgameMenu_DrawAwardsMedals( awardNum + 1 );
  232.  
  233.     if( !postgameMenuInfo.playedSound[awardNum] ) {
  234.         postgameMenuInfo.playedSound[awardNum] = qtrue;
  235.         trap_S_StartLocalSound( trap_S_RegisterSound( ui_medalSounds[postgameMenuInfo.awardsEarned[awardNum]] ), CHAN_ANNOUNCER );
  236.     }
  237. }
  238.  
  239.  
  240. /*
  241. =================
  242. UI_SPPostgameMenu_MenuDrawScoreLine
  243. =================
  244. */
  245. static void UI_SPPostgameMenu_MenuDrawScoreLine( int n, int y ) {
  246.     int        rank;
  247.     char    name[64];
  248.     char    info[MAX_INFO_STRING];
  249.  
  250.     if( n > (postgameMenuInfo.numClients + 1) ) {
  251.         n -= (postgameMenuInfo.numClients + 2);
  252.     }
  253.  
  254.     if( n >= postgameMenuInfo.numClients ) {
  255.         return;
  256.     }
  257.  
  258.     rank = postgameMenuInfo.ranks[n];
  259.     if( rank & RANK_TIED_FLAG ) {
  260.         UI_DrawString( 640 - 31 * SMALLCHAR_WIDTH, y, "(tie)", UI_LEFT|UI_SMALLFONT, color_white );
  261.         rank &= ~RANK_TIED_FLAG;
  262.     }
  263.     trap_GetConfigString( CS_PLAYERS + postgameMenuInfo.clientNums[n], info, MAX_INFO_STRING );
  264.     Q_strncpyz( name, Info_ValueForKey( info, "n" ), sizeof(name) );
  265.     Q_CleanStr( name );
  266.  
  267.     UI_DrawString( 640 - 25 * SMALLCHAR_WIDTH, y, va( "#%i: %-16s %2i", rank + 1, name, postgameMenuInfo.scores[n] ), UI_LEFT|UI_SMALLFONT, color_white );
  268. }
  269.  
  270.  
  271. /*
  272. =================
  273. UI_SPPostgameMenu_MenuDraw
  274. =================
  275. */
  276. static void UI_SPPostgameMenu_MenuDraw( void ) {
  277.     int        timer;
  278.     int        serverId;
  279.     int        n;
  280.     char    info[MAX_INFO_STRING];
  281.  
  282.     trap_GetConfigString( CS_SYSTEMINFO, info, sizeof(info) );
  283.     serverId = atoi( Info_ValueForKey( info, "sv_serverid" ) );
  284.     if( serverId != postgameMenuInfo.serverId ) {
  285.         UI_PopMenu();
  286.         return;
  287.     }
  288.  
  289.     // phase 1
  290.     if ( postgameMenuInfo.numClients > 2 ) {
  291.         UI_DrawProportionalString( 510, 480 - 64 - PROP_HEIGHT, postgameMenuInfo.placeNames[2], UI_CENTER, color_white );
  292.     }
  293.     UI_DrawProportionalString( 130, 480 - 64 - PROP_HEIGHT, postgameMenuInfo.placeNames[1], UI_CENTER, color_white );
  294.     UI_DrawProportionalString( 320, 480 - 64 - 2 * PROP_HEIGHT, postgameMenuInfo.placeNames[0], UI_CENTER, color_white );
  295.  
  296.     if( postgameMenuInfo.phase == 1 ) {
  297.         timer = uis.realtime - postgameMenuInfo.starttime;
  298.  
  299.         if( timer >= 1000 && postgameMenuInfo.winnerSound ) {
  300.             trap_S_StartLocalSound( postgameMenuInfo.winnerSound, CHAN_ANNOUNCER );
  301.             postgameMenuInfo.winnerSound = 0;
  302.         }
  303.  
  304.         if( timer < 5000 ) {
  305.             return;
  306.         }
  307.         postgameMenuInfo.phase = 2;
  308.         postgameMenuInfo.starttime = uis.realtime;
  309.     }
  310.  
  311.     // phase 2
  312.     if( postgameMenuInfo.phase == 2 ) {
  313.         timer = uis.realtime - postgameMenuInfo.starttime;
  314.         if( timer >= ( postgameMenuInfo.numAwards * AWARD_PRESENTATION_TIME ) ) {
  315.             postgameMenuInfo.phase = 3;
  316.             postgameMenuInfo.starttime = uis.realtime;
  317.         }
  318.         else {
  319.             UI_SPPostgameMenu_DrawAwardsPresentation( timer );
  320.         }
  321.     }
  322.  
  323.     // phase 3
  324.     if( postgameMenuInfo.phase == 3 ) {
  325.         if( uis.demoversion ) {
  326.             if( postgameMenuInfo.won == 1 && UI_ShowTierVideo( 8 )) {
  327.                 trap_Cvar_Set( "nextmap", "" );
  328.                 trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect; cinematic demoEnd.RoQ\n" );
  329.                 return;
  330.             }
  331.         }
  332.         else if( postgameMenuInfo.won > -1 && UI_ShowTierVideo( postgameMenuInfo.won + 1 )) {
  333.             if( postgameMenuInfo.won == postgameMenuInfo.lastTier ) {
  334.                 trap_Cvar_Set( "nextmap", "" );
  335.                 trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect; cinematic end.RoQ\n" );
  336.                 return;
  337.             }
  338.  
  339.             trap_Cvar_SetValue( "ui_spSelection", postgameMenuInfo.won * ARENAS_PER_TIER );
  340.             trap_Cvar_Set( "nextmap", "levelselect" );
  341.             trap_Cmd_ExecuteText( EXEC_APPEND, va( "disconnect; cinematic tier%i.RoQ\n", postgameMenuInfo.won + 1 ) );
  342.             return;
  343.         }
  344.  
  345.         postgameMenuInfo.item_again.generic.flags &= ~QMF_INACTIVE;
  346.         postgameMenuInfo.item_next.generic.flags &= ~QMF_INACTIVE;
  347.         postgameMenuInfo.item_menu.generic.flags &= ~QMF_INACTIVE;
  348.  
  349.         UI_SPPostgameMenu_DrawAwardsMedals( postgameMenuInfo.numAwards );
  350.  
  351.         Menu_Draw( &postgameMenuInfo.menu );
  352.     }
  353.  
  354.     // draw the scoreboard
  355.     if( !trap_Cvar_VariableValue( "ui_spScoreboard" ) ) {
  356.         return;
  357.     }
  358.  
  359.     timer = uis.realtime - postgameMenuInfo.scoreboardtime;
  360.     if( postgameMenuInfo.numClients <= 3 ) {
  361.         n = 0;
  362.     }
  363.     else {
  364.         n = timer / 1500 % (postgameMenuInfo.numClients + 2);
  365.     }
  366.     UI_SPPostgameMenu_MenuDrawScoreLine( n, 0 );
  367.     UI_SPPostgameMenu_MenuDrawScoreLine( n + 1, 0 + SMALLCHAR_HEIGHT );
  368.     UI_SPPostgameMenu_MenuDrawScoreLine( n + 2, 0 + 2 * SMALLCHAR_HEIGHT );
  369. }
  370.  
  371.  
  372. /*
  373. =================
  374. UI_SPPostgameMenu_Cache
  375. =================
  376. */
  377. void UI_SPPostgameMenu_Cache( void ) {
  378.     int            n;
  379.     qboolean    buildscript;
  380.  
  381.     buildscript = trap_Cvar_VariableValue("com_buildscript");
  382.  
  383.     trap_R_RegisterShaderNoMip( ART_MENU0 );
  384.     trap_R_RegisterShaderNoMip( ART_MENU1 );
  385.     trap_R_RegisterShaderNoMip( ART_REPLAY0 );
  386.     trap_R_RegisterShaderNoMip( ART_REPLAY1 );
  387.     trap_R_RegisterShaderNoMip( ART_NEXT0 );
  388.     trap_R_RegisterShaderNoMip( ART_NEXT1 );
  389.     for( n = 0; n < 6; n++ ) {
  390.         trap_R_RegisterShaderNoMip( ui_medalPicNames[n] );
  391.         trap_S_RegisterSound( ui_medalSounds[n] );
  392.     }
  393.  
  394.     if( buildscript ) {
  395.         trap_S_RegisterSound( "music music/loss.wav" );
  396.         trap_S_RegisterSound( "music music/win.wav" );
  397.         trap_S_RegisterSound( "sound/player/announce/youwin.wav" );
  398.     }
  399. }
  400.  
  401.  
  402. /*
  403. =================
  404. UI_SPPostgameMenu_Init
  405. =================
  406. */
  407. static void UI_SPPostgameMenu_Init( void ) {
  408.     postgameMenuInfo.menu.wrapAround    = qtrue;
  409.     postgameMenuInfo.menu.key            = UI_SPPostgameMenu_MenuKey;
  410.     postgameMenuInfo.menu.draw            = UI_SPPostgameMenu_MenuDraw;
  411.     postgameMenuInfo.ignoreKeysTime        = uis.realtime + 1500;
  412.  
  413.     UI_SPPostgameMenu_Cache();
  414.  
  415.     postgameMenuInfo.item_menu.generic.type            = MTYPE_BITMAP;
  416.     postgameMenuInfo.item_menu.generic.name            = ART_MENU0;
  417.     postgameMenuInfo.item_menu.generic.flags        = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_INACTIVE;
  418.     postgameMenuInfo.item_menu.generic.x            = 0;
  419.     postgameMenuInfo.item_menu.generic.y            = 480-64;
  420.     postgameMenuInfo.item_menu.generic.callback        = UI_SPPostgameMenu_MenuEvent;
  421.     postgameMenuInfo.item_menu.generic.id            = ID_MENU;
  422.     postgameMenuInfo.item_menu.width                = 128;
  423.     postgameMenuInfo.item_menu.height                = 64;
  424.     postgameMenuInfo.item_menu.focuspic                = ART_MENU1;
  425.  
  426.     postgameMenuInfo.item_again.generic.type        = MTYPE_BITMAP;
  427.     postgameMenuInfo.item_again.generic.name        = ART_REPLAY0;
  428.     postgameMenuInfo.item_again.generic.flags        = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS|QMF_INACTIVE;
  429.     postgameMenuInfo.item_again.generic.x            = 320;
  430.     postgameMenuInfo.item_again.generic.y            = 480-64;
  431.     postgameMenuInfo.item_again.generic.callback    = UI_SPPostgameMenu_AgainEvent;
  432.     postgameMenuInfo.item_again.generic.id            = ID_AGAIN;
  433.     postgameMenuInfo.item_again.width                = 128;
  434.     postgameMenuInfo.item_again.height                = 64;
  435.     postgameMenuInfo.item_again.focuspic            = ART_REPLAY1;
  436.  
  437.     postgameMenuInfo.item_next.generic.type            = MTYPE_BITMAP;
  438.     postgameMenuInfo.item_next.generic.name            = ART_NEXT0;
  439.     postgameMenuInfo.item_next.generic.flags        = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_INACTIVE;
  440.     postgameMenuInfo.item_next.generic.x            = 640;
  441.     postgameMenuInfo.item_next.generic.y            = 480-64;
  442.     postgameMenuInfo.item_next.generic.callback        = UI_SPPostgameMenu_NextEvent;
  443.     postgameMenuInfo.item_next.generic.id            = ID_NEXT;
  444.     postgameMenuInfo.item_next.width                = 128;
  445.     postgameMenuInfo.item_next.height                = 64;
  446.     postgameMenuInfo.item_next.focuspic                = ART_NEXT1;
  447.  
  448.     Menu_AddItem( &postgameMenuInfo.menu, ( void * )&postgameMenuInfo.item_menu );
  449.     Menu_AddItem( &postgameMenuInfo.menu, ( void * )&postgameMenuInfo.item_again );
  450.     Menu_AddItem( &postgameMenuInfo.menu, ( void * )&postgameMenuInfo.item_next );
  451. }
  452.  
  453.  
  454. static void Prepname( int index ) {
  455.     int        len;
  456.     char    name[64];
  457.     char    info[MAX_INFO_STRING];
  458.  
  459.     trap_GetConfigString( CS_PLAYERS + postgameMenuInfo.clientNums[index], info, MAX_INFO_STRING );
  460.     Q_strncpyz( name, Info_ValueForKey( info, "n" ), sizeof(name) );
  461.     Q_CleanStr( name );
  462.     len = strlen( name );
  463.  
  464.     while( len && UI_ProportionalStringWidth( name ) > 256 ) {
  465.         len--;
  466.         name[len] = 0;
  467.     }
  468.  
  469.     Q_strncpyz( postgameMenuInfo.placeNames[index], name, sizeof(postgameMenuInfo.placeNames[index]) );
  470. }
  471.  
  472.  
  473. /*
  474. =================
  475. UI_SPPostgameMenu_f
  476. =================
  477. */
  478. void UI_SPPostgameMenu_f( void ) {
  479.     int            playerGameRank;
  480.     int            playerClientNum;
  481.     int            n;
  482.     int            oldFrags, newFrags;
  483.     const char    *arena;
  484.     int            awardValues[6];
  485.     char        map[MAX_QPATH];
  486.     char        info[MAX_INFO_STRING];
  487.  
  488.     memset( &postgameMenuInfo, 0, sizeof(postgameMenuInfo) );
  489.  
  490.     trap_GetConfigString( CS_SYSTEMINFO, info, sizeof(info) );
  491.     postgameMenuInfo.serverId = atoi( Info_ValueForKey( info, "sv_serverid" ) );
  492.  
  493.     trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) );
  494.     Q_strncpyz( map, Info_ValueForKey( info, "mapname" ), sizeof(map) );
  495.     arena = UI_GetArenaInfoByMap( map );
  496.     if ( !arena ) {
  497.         return;
  498.     }
  499.     Q_strncpyz( arenainfo, arena, sizeof(arenainfo) );
  500.  
  501.     postgameMenuInfo.level = atoi( Info_ValueForKey( arenainfo, "num" ) );
  502.  
  503.     postgameMenuInfo.numClients = atoi( UI_Argv( 1 ) );
  504.     playerClientNum = atoi( UI_Argv( 2 ) );
  505.     playerGameRank = 8;        // in case they ended game as a spectator
  506.  
  507.     if( postgameMenuInfo.numClients > MAX_SCOREBOARD_CLIENTS ) {
  508.         postgameMenuInfo.numClients = MAX_SCOREBOARD_CLIENTS;
  509.     }
  510.  
  511.     for( n = 0; n < postgameMenuInfo.numClients; n++ ) {
  512.         postgameMenuInfo.clientNums[n] = atoi( UI_Argv( 8 + n * 3 + 1 ) );
  513.         postgameMenuInfo.ranks[n] = atoi( UI_Argv( 8 + n * 3 + 2 ) );
  514.         postgameMenuInfo.scores[n] = atoi( UI_Argv( 8 + n * 3 + 3 ) );
  515.  
  516.         if( postgameMenuInfo.clientNums[n] == playerClientNum ) {
  517.             playerGameRank = (postgameMenuInfo.ranks[n] & ~RANK_TIED_FLAG) + 1;
  518.         }
  519.     }
  520.  
  521.     UI_SetBestScore( postgameMenuInfo.level, playerGameRank );
  522.  
  523.     // process award stats and prepare presentation data
  524.     awardValues[AWARD_ACCURACY] = atoi( UI_Argv( 3 ) );
  525.     awardValues[AWARD_IMPRESSIVE] = atoi( UI_Argv( 4 ) );
  526.     awardValues[AWARD_EXCELLENT] = atoi( UI_Argv( 5 ) );
  527.     awardValues[AWARD_GAUNTLET] = atoi( UI_Argv( 6 ) );
  528.     awardValues[AWARD_FRAGS] = atoi( UI_Argv( 7 ) );
  529.     awardValues[AWARD_PERFECT] = atoi( UI_Argv( 8 ) );
  530.  
  531.     postgameMenuInfo.numAwards = 0;
  532.  
  533.     if( awardValues[AWARD_ACCURACY] >= 50 ) {
  534.         UI_LogAwardData( AWARD_ACCURACY, 1 );
  535.         postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_ACCURACY;
  536.         postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = awardValues[AWARD_ACCURACY];
  537.         postgameMenuInfo.numAwards++;
  538.     }
  539.  
  540.     if( awardValues[AWARD_IMPRESSIVE] ) {
  541.         UI_LogAwardData( AWARD_IMPRESSIVE, awardValues[AWARD_IMPRESSIVE] );
  542.         postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_IMPRESSIVE;
  543.         postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = awardValues[AWARD_IMPRESSIVE];
  544.         postgameMenuInfo.numAwards++;
  545.     }
  546.  
  547.     if( awardValues[AWARD_EXCELLENT] ) {
  548.         UI_LogAwardData( AWARD_EXCELLENT, awardValues[AWARD_EXCELLENT] );
  549.         postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_EXCELLENT;
  550.         postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = awardValues[AWARD_EXCELLENT];
  551.         postgameMenuInfo.numAwards++;
  552.     }
  553.  
  554.     if( awardValues[AWARD_GAUNTLET] ) {
  555.         UI_LogAwardData( AWARD_GAUNTLET, awardValues[AWARD_GAUNTLET] );
  556.         postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_GAUNTLET;
  557.         postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = awardValues[AWARD_GAUNTLET];
  558.         postgameMenuInfo.numAwards++;
  559.     }
  560.  
  561.     oldFrags = UI_GetAwardLevel( AWARD_FRAGS ) / 100;
  562.     UI_LogAwardData( AWARD_FRAGS, awardValues[AWARD_FRAGS] );
  563.     newFrags = UI_GetAwardLevel( AWARD_FRAGS ) / 100;
  564.     if( newFrags > oldFrags ) {
  565.         postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_FRAGS;
  566.         postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = newFrags * 100;
  567.         postgameMenuInfo.numAwards++;
  568.     }
  569.  
  570.     if( awardValues[AWARD_PERFECT] ) {
  571.         UI_LogAwardData( AWARD_PERFECT, 1 );
  572.         postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_PERFECT;
  573.         postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = 1;
  574.         postgameMenuInfo.numAwards++;
  575.     }
  576.  
  577.     if ( playerGameRank == 1 ) {
  578.         postgameMenuInfo.won = UI_TierCompleted( postgameMenuInfo.level );
  579.     }
  580.     else {
  581.         postgameMenuInfo.won = -1;
  582.     }
  583.  
  584.     postgameMenuInfo.starttime = uis.realtime;
  585.     postgameMenuInfo.scoreboardtime = uis.realtime;
  586.  
  587.     trap_Key_SetCatcher( KEYCATCH_UI );
  588.     uis.menusp = 0;
  589.  
  590.     UI_SPPostgameMenu_Init();
  591.     UI_PushMenu( &postgameMenuInfo.menu );
  592.  
  593.     if ( playerGameRank == 1 ) {
  594.         Menu_SetCursorToItem( &postgameMenuInfo.menu, &postgameMenuInfo.item_next );
  595.     }
  596.     else {
  597.         Menu_SetCursorToItem( &postgameMenuInfo.menu, &postgameMenuInfo.item_again );
  598.     }
  599.  
  600.     Prepname( 0 );
  601.     Prepname( 1 );
  602.     Prepname( 2 );
  603.  
  604.     if ( playerGameRank != 1 ) {
  605.         postgameMenuInfo.winnerSound = trap_S_RegisterSound( va( "sound/player/announce/%s_wins.wav", postgameMenuInfo.placeNames[0] ) );
  606.         trap_Cmd_ExecuteText( EXEC_APPEND, "music music/loss\n" );
  607.     }
  608.     else {
  609.         postgameMenuInfo.winnerSound = trap_S_RegisterSound( "sound/player/announce/youwin.wav" );
  610.         trap_Cmd_ExecuteText( EXEC_APPEND, "music music/win\n" );
  611.     }
  612.  
  613.     postgameMenuInfo.phase = 1;
  614.  
  615.     postgameMenuInfo.lastTier = UI_GetNumSPTiers();
  616.     if ( UI_GetSpecialArenaInfo( "final" ) ) {
  617.         postgameMenuInfo.lastTier++;
  618.     }
  619. }
  620.